package app.caretrack.model;

import java.io.Serializable;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@Entity
@Table(name = "LogData")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class LogData implements Serializable {

    private static final long serialVersionUID = 1L;

    private int id;
    /**
     * The machine that reported this LogData
     */
    private Machine machine;
    /**
     * Timestamp of report, when the data was sent
     */
    private java.util.Date timestamp;
    /**
     * If a failed later log data was received where we stored a daily hours the
     * timestamp of this is stored here
     */
    private java.util.Date dailyHoursTimestamp;
    /**
     * If a failed later log data was received where we stored a daily hours the
     * machine hours of this is stored here
     */
    private Integer dailyHoursMachineHours;
    /**
     * Accumulated machine hours in minutes (engine on time) Must be set if this
     * log data is a utilization report, ie matrisData is false
     */
    private int machineHours;
    /**
     * List of the reported LogID values
     */
    private List<LogId> logIds;

    /**
     * If the data should be compiled into a Matris file
     */
    private boolean matrisData;
    /**
     * If the data has been processed, used while data is not cleared after
     * processing
     */
    private boolean processed;
    /**
     * If the data is completely downloaded and ready to be processed
     */
    private boolean complete;

    /**
     * @return Returns the id.
     */
    @Id
    @SequenceGenerator(name = "LOGDATA_SEQ", sequenceName = "LOGDATA_SEQ", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "LOGDATA_SEQ")
    public int getId() {
        return this.id;
    }

    /**
     * @param id The id to set.
     */
    public void setId(int id) {
        this.id = id;
    }

    /**
     * @return Returns the logIDs. [BAG ISSUE]
     */
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "logData", cascade = CascadeType.ALL)
    public List<LogId> getLogIds() {
        return this.logIds;
    }

    /**
     * @param logIds The logIDs to set.
     */
    public void setLogIds(List<LogId> logIds) {
        this.logIds = logIds;
    }

    /**
     * @return Returns the machine.
     */
    @ManyToOne(fetch = FetchType.LAZY)
    public Machine getMachine() {
        return this.machine;
    }

    /**
     * @param machine The machine to set.
     */
    public void setMachine(Machine machine) {
        this.machine = machine;
    }

    /**
     * @return Returns the timestamp.
     */
    @Column(columnDefinition = "DATE")
    public Date getTimestamp() {
        return this.timestamp;
    }

    /**
     * @param timestamp The timestamp to set.
     */
    public void setTimestamp(Date timestamp) {
        this.timestamp = timestamp;
    }

    /**
     * @return Returns the matrisData.
     */
    public boolean isMatrisData() {
        return this.matrisData;
    }

    /**
     * @param matrisData The matrisData to set.
     */
    public void setMatrisData(boolean matrisData) {
        this.matrisData = matrisData;
    }

    /**
     * @return Returns the processed.
     */
    public boolean isProcessed() {
        return this.processed;
    }

    /**
     * @param processed The processed to set.
     */
    public void setProcessed(boolean processed) {
        this.processed = processed;
    }

    @Override
    public String toString() {
        StringBuilder str = new StringBuilder();
        str.append("Id: " + this.id + ", ");
        str.append("MachineID: " + this.machine.getId() + ", ");
        str.append("Timestamp: " + this.timestamp + ", ");
        return str.toString();
    }

    /**
     * Find the LogID in this LogData with the specified logID
     * 
     * @param id The id to match
     * @return LogID with the same logID as id
     */
    public LogId getLogID(int id) {
        Iterator<LogId> iter = this.logIds.iterator();
        while (iter.hasNext()) {
            LogId l = iter.next();
            if (l.getLogId() == id) {
                return l;
            }
        }
        return null;
    }

    /**
     * @return Machine hours in minutes
     */
    public int getMachineHours() {
        return this.machineHours;
    }

    /**
     * @param machineHours Machine hours in minutes
     */
    public void setMachineHours(int machineHours) {
        this.machineHours = machineHours;
    }

    /**
     * @return Returns the complete.
     */
    public boolean isComplete() {
        return this.complete;
    }

    /**
     * @param complete The complete to set.
     */
    public void setComplete(boolean complete) {
        this.complete = complete;
    }

    /**
     * @return the dailyHoursMachineHours
     */
    public Integer getDailyHoursMachineHours() {
        return this.dailyHoursMachineHours;
    }

    /**
     * @param dailyHoursMachineHours the dailyHoursMachineHours to set
     */
    public void setDailyHoursMachineHours(Integer dailyHoursMachineHours) {
        this.dailyHoursMachineHours = dailyHoursMachineHours;
    }

    /**
     * @return the dailyHoursTimestamp
     */
    @Column(columnDefinition = "DATE")
    public java.util.Date getDailyHoursTimestamp() {
        return this.dailyHoursTimestamp;
    }

    /**
     * @param dailyHoursTimestamp the dailyHoursTimestamp to set
     */
    public void setDailyHoursTimestamp(java.util.Date dailyHoursTimestamp) {
        this.dailyHoursTimestamp = dailyHoursTimestamp;
    }

}
